<template>
  <div>
    <BasicTable @register="registerDeviceTable">
      <template #headerTop>
        <Alert v-if="checkedKeys.length > 0" type="info" show-icon style="position: relative">
          <template #message>
            <div>
              <span>已选中{{ checkedKeys.length }}条记录</span>
              <div style="position: absolute; top: 4px; right: 10px">
                <Tooltip title="删除">
                  <a-button type="text" @click="handleSelectedDelete">
                    <Icon :icon="ICON.DELETE" color="#0960bd" />
                  </a-button>
                </Tooltip>
              </div>
            </div>
          </template>
        </Alert>
      </template>
      <template #toolbar>
        <a-button type="primary" @click="() => openAddPacketModal(true)">添加包</a-button>
      </template>
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'action'">
          <TableAction
            :stopButtonPropagation="true"
            :actions="[
              {
                icon: ICON.EDIT,
                tooltip: {
                  title: '编辑',
                  placement: 'top',
                },
                onClick: openEditModal.bind(null, true, { record }),
              },
              {
                icon: ICON.CHECK,
                tooltip: {
                  title: '查看',
                  placement: 'top',
                },
                onClick: handleDetail.bind(null, record),
              },
              {
                icon: ICON.DELETE,
                tooltip: {
                  title: '删除',
                  placement: 'top',
                },
                onClick: handleDelete.bind(null, record),
              },
            ]"
            :drop-down-actions="[
              {
                icon: ICON.DOWNLOAD,
                label: '下载',
                disabled: !record.dataSize,
                onClick: handleDownload.bind(null, record),
              },
            ]"
          />
        </template>
      </template>
    </BasicTable>
    <OtaDrawer @register="registerDrawer" />
    <AddPacketModal @register="registerAddPacketModal" @success="handleSuccess" />
    <EditModal @register="registerEditModal" @success="handleSuccess" />
  </div>
</template>

<script setup lang="ts">
  import { BasicTable, useTable, TableAction } from '/@/components/Table';
  import { OTATableSchema, searchSchema } from './index.data';
  import { ICON } from '/@/enums/iconEnum';
  import OtaDrawer from './components/OtaDrawer.vue';
  import AddPacketModal from './components/AddPacketModal.vue';
  import Icon from '/@/components/Icon';
  import { useDrawer } from '/@/components/Drawer';
  import { useModal } from '/@/components/Modal';
  import { useMessage } from '/@/hooks/web/useMessage';
  import EditModal from './components/EditModal.vue';
  import { Alert, Tooltip } from 'ant-design-vue';
  import { onMounted, ref } from 'vue';
  import {
    otaPackages,
    addPackage,
    uploadFile,
    updatePackage,
    downloadPackage,
    deletePackage,
  } from '/@/api/thingsborad/advanced/OTA/OTA';
  import {
    OTATableParams,
    OTAPackageAddParams,
    OTAPackageItem,
  } from '/@/api/thingsborad/advanced/OTA/OTAModel';
  import { saveAs } from 'file-saver';
  import { tableFormStyleSetting } from '/@/settings/thingsBoardDesign';
  const checkedKeys = ref<any>([]);
  const [registerDeviceTable, { setProps, reload }] = useTable({
    title: '包仓库',
    columns: OTATableSchema,
    showIndexColumn: false,
    immediate: true,
    showSummary: false,
    clickToRowSelect: false,
    showTableSetting: true,
    useSearchForm: true,
    formConfig: {
      layout: 'horizontal',
      schemas: searchSchema,
      showAdvancedButton: false,
      ...tableFormStyleSetting,
      actionColOptions: {
        md: { span: 8, offset: 8 },
        lg: { span: 6, offset: 12 },
        xl: { span: 4, offset: 16 },
        xxl: { span: 4, offset: 16 },
      },
      submitFunc: async () => {
        reload();
      },
    },
    actionColumn: {
      title: '操作',
      width: 150,
      flag: 'ACTION',
      dataIndex: 'action',
    },
    rowKey: 'id',
    rowSelection: {
      type: 'checkbox',
      selectedRowKeys: checkedKeys,
      onSelect: onSelect,
      onSelectAll: onSelectAll,
    },
  });
  const [registerDrawer, { openDrawer }] = useDrawer();
  const { createConfirm } = useMessage();
  const [registerAddPacketModal, { openModal: openAddPacketModal }] = useModal();
  const [registerEditModal, { openModal: openEditModal }] = useModal();
  // 删除
  function handleDelete(record: Recordable) {
    createConfirm({
      iconType: 'info',
      title: `确定要删除"${record.title}"OTA升级吗？`,
      content: '请注意：确认后，OTA升级将不可恢复。',
      onOk: async () => {
        await deletePackage(record.otaPackageId);
        reload();
      },
    });
  }
  // 详情
  function handleDetail(record: Recordable) {
    openDrawer(true, {
      otaPackageId: record.otaPackageId,
    });
  }
  // 下载
  const handleDownload = async (record: Recordable) => {
    const values = await downloadPackage(record.otaPackageId);
    const blob = new Blob([values]);
    saveAs(blob, record.fileName);
  };
  // 多选
  function onSelect(record: Recordable, selected: boolean) {
    if (selected) {
      checkedKeys.value = [...checkedKeys.value, record.id];
    } else {
      checkedKeys.value = checkedKeys.value.filter((id) => id !== record.id);
    }
  }
  // 全选
  function onSelectAll(selected: boolean, _selectedRows: Recordable[], changeRows: Recordable[]) {
    const changeIds = changeRows.map((item) => item.id);
    if (selected) {
      checkedKeys.value = [...checkedKeys.value, ...changeIds];
    } else {
      checkedKeys.value = checkedKeys.value.filter((id) => {
        return !changeIds.includes(id);
      });
    }
  }
  // 多选删除
  const handleSelectedDelete = () => {
    createConfirm({
      iconType: 'info',
      title: `确定要删除${checkedKeys.value.length}个资产吗？`,
      content: '请注意：确认后，设备及其所有相关数据将不可恢复。',
      onOk: async () => {
        setProps({ loading: true });
        for (const item of checkedKeys.value) {
          await deletePackage(item.id);
        }
        reload();
        checkedKeys.value = [];
      },
    });
  };
  // 弹窗操作
  const handleSuccess = async ({ key, values }) => {
    if (key == 'add') {
      if (values.uploadMethod == 'URL') {
        let params: OTAPackageAddParams = {
          title: values.title,
          version: values.version,
          tag: values.versionLabel,
          type: values.packetType,
          deviceProfileId: JSON.parse(values.deviceConfiguration),
          checksumAlgorithm: values.algorithm,
          checksum: null,
          url: values.URL,
          isURL: true,
          additionalInfo: { description: values.remark },
        };
        await addPackage(params);
        reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
      } else {
        let params: OTAPackageAddParams = {
          title: values.title,
          version: values.version,
          tag: values.versionLabel,
          type: values.packetType,
          deviceProfileId: JSON.parse(values.deviceConfiguration),
          isURL: false,
          additionalInfo: { description: values.remark },
        };

        const res: OTAPackageItem = await addPackage(params);
        const formData = new FormData();
        formData.append('file', values.localPacket);
        let uploadParams = {
          id: res.id.id,
          checksumAlgorithm: values.algorithm,
          file: formData,
        };
        await uploadFile(uploadParams);
        reload({ sortInfo: { field: 'createdTime', order: 'DESC' } });
      }
    } else if (key == 'edit') {
      values.record.additionalInfo.description = values.values.remark;
      await updatePackage(values.record);
      reload();
    }
  };

  onMounted(async () => {
    setProps({
      api: otaPackages,
      beforeFetch: (val) => {
        let params: OTATableParams = {
          page: val.page - 1,
          pageSize: val.pageSize,
          sortOrder: val.order == 'ascend' ? 'ASC' : 'DESC',
          sortProperty: val.field,
        };
        val?.textSearch ? (params.textSearch = val.textSearch) : null;
        return params;
      },
      afterFetch: (res) => {
        let list: any[] = [];
        res.length != 0
          ? res.forEach((item: any) => {
              let tableItem = {
                createdTime: item.createdTime,
                title: item.title,
                version: item.version,
                versionLabel: item.tag,
                packetType: item.type,
                URL: item.url,
                fileName: item.fileName,
                fileSize: item.dataSize,
                checkSum: item.checksum,
                otaPackageId: item.id.id,
                dataSize: Boolean(item.dataSize),
                id: item.id.id,
              };
              list.push(tableItem);
            })
          : null;
        return list;
      },
      fetchSetting: {
        pageField: 'page',
        sizeField: 'pageSize',
        listField: 'data',
        totalField: 'totalElements',
      },
    });
    reload();
  });
</script>
